package com.shawn.admin.service;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shawn.admin.exception.BusinessException;
import com.shawn.admin.mapper.LogMapper;
import com.shawn.commons.utils.CommentType;
import com.shawn.commons.utils.RC;
import com.shawn.dubbo.api.*;
import com.shawn.model.entity.Log;
import com.shawn.model.entity.Question;
import com.shawn.model.entity.User;
import com.shawn.model.entity.UserInfo;
import com.shawn.model.mongo.Comment;
import com.shawn.model.mongo.Movement;
import com.shawn.model.mongo.Video;
import com.shawn.model.sqldto.UserLogDto;
import com.shawn.model.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
public class ManageService {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Resource
    private LogMapper logMapper;

    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private QuestionApi questionApi;

    @DubboReference
    private UserApi userApi;


    @DubboReference
    private MovementApi movementApi;


    @DubboReference
    private CommentsApi commentsApi;


    @DubboReference
    private VideoApi videoApi;
    /**
     * 得到用户页面
     *
     * @param page     页面
     * @param pageSize 页面大小
     * @return {@link PageResult}<{@link UserInfoVo}>
     */
    public PageResult<UserDetailInfoVo> getUsersByPage(Integer page, Integer pageSize,Long id,String nickname,String city) {

        PageResult<UserInfo> pageResult = userInfoApi.selectByPage(page, pageSize,id,nickname,city);
        if (Objects.nonNull(pageResult)&&pageResult.getItems().size()>0){
            List<UserInfo> userInfos = pageResult.getItems();
            //批量查询当前用户
            List<Long> ids = userInfos.stream().map(UserInfo::getId).collect(Collectors.toList());
            List<LogVo> logVos = logMapper.selectLoginTime(ids);
            Map<Long, LogVo> logVoMap = CollUtil.fieldValueMap(logVos, "userId");

            List<UserDetailInfoVo> vos = userInfos.stream().map((userInfo) -> {
                String key = RC.FREEZING_USER + userInfo.getId();
                Boolean hasKey = redisTemplate.hasKey(key);
                if (Boolean.TRUE.equals(hasKey)) {
                    userInfo.setUserStatus(RC.FREEZING_FROZEN_STATUS);
                }
                UserDetailInfoVo vo = new UserDetailInfoVo();
                BeanUtils.copyProperties(userInfo, vo);
                if (Objects.nonNull(logVoMap.get(userInfo.getId()))){
                    vo.setLastActiveTime(logVoMap.get(userInfo.getId()).getUpdated());
                }
                vo.setSex("man".equals(userInfo.getGender()) ? "男" : "女");
                return vo;
            }).collect(Collectors.toList());
            return new PageResult<>(page,pageSize,pageResult.getPages(),vos);
        }
        return new PageResult<>(page,pageSize,0,new ArrayList<>());
    }

    public UserPersonalVo selectUserById(Long userId) {
        UserInfo userInfo = userInfoApi.findDetailById(userId);
        //查询当前用户最近登录时间
        UserLogDto userLogDto = logMapper.selectLatestLoginTime(userId);
        Date lastActiveTime = userLogDto.getLogTime();
        String lastLoginLocation = userLogDto.getPlace();
        //查询用户手机号
        String mobile = userApi.findById(userId).getMobile();
        //查询用户个性签名
        String personalSignature = questionApi.getQuestionByUserId(userId).getTxt();
        //查询用户的粉丝,关注者,互关数量
        Map<String, Integer> map = userLikeApi.getFriendsDetailCount(userId);
        Integer countMatching = map.get("eachLoveCount");
        Integer countLiked = map.get("loveCount");
        Integer countBeLiked = map.get("fanCount");
        //修改查询用户信息,便于显示用户状态
        String key = RC.FREEZING_USER+userId;
        Boolean hasKey = redisTemplate.hasKey(key);
        if (Boolean.TRUE.equals(hasKey)){
            userInfo.setUserStatus(RC.FREEZING_FROZEN_STATUS);
        }
        UserPersonalVo vo = new UserPersonalVo();
        BeanUtils.copyProperties(userInfo,vo);
        vo.setLastActiveTime(lastActiveTime);
        vo.setLastLoginLocation(lastLoginLocation);
        vo.setMobile(mobile);
        vo.setPersonalSignature(personalSignature);
        vo.setCountMatching(countMatching);
        vo.setCountLiked(countLiked);
        vo.setCountBeLiked(countBeLiked);
        vo.setSex("man".equals(userInfo.getGender())?"男":"女");
        vo.setIncome(Integer.parseInt(userInfo.getIncome()));
        vo.setOccupation(userInfo.getProfession());
        vo.setLogo(userInfo.getAvatar());
        return vo;
    }

    /**
     * 得到动态分页查询
     *
     * @param page     页面
     * @param pageSize 页面大小
     * @param userId   用户id
     * @param state    状态
     * @return {@link PageResult}<{@link MovementsVo}>
     */
    public PageResult<MovementDetailVo> getMovByPage(Integer page, Integer pageSize, Long userId, Integer state) {
        //获取当前用户信息
        UserInfo userInfo = userInfoApi.findDetailById(userId);
        //分页按时间降序获取所有指定状态的动态
       PageResult<Movement> pageResult = movementApi.selectByCondition(page,pageSize,userId,state);

        if (Objects.isNull(pageResult.getItems())||pageResult.getItems().size()==0){
            return new PageResult<>();
        }
       //转化vo对象
        List<Movement> movements = pageResult.getItems();
        List<MovementDetailVo> movementsVos = movements.stream().map(mov -> {
            if(Objects.isNull(userInfo)){
                UserInfo info = userInfoApi.findDetailById(mov.getUserId());
                return MovementDetailVo.init(info, mov);
            }
          return MovementDetailVo.init(userInfo, mov);
        }).collect(Collectors.toList());

        return new PageResult<>(page,pageSize,pageResult.getCounts(),movementsVos);
    }

    public PageResult<VideoBackendVo> getVideoByPage(Integer page, Integer pageSize, Long userId,String sortProp,String sortOrder) {
        PageResult<Video> pageResult = videoApi.getVideoByPage(page, pageSize, userId,sortProp,sortOrder);
        if (pageResult.getCounts()==0){
            return new PageResult<>();
        }
        List<Video> videos = pageResult.getItems();
        List<Long> ids = videos.stream().map(Video::getUserId).collect(Collectors.toList());
        List<UserInfo> infos = userInfoApi.findByIds(ids);
        Map<Long, UserInfo> infoMap = CollUtil.fieldValueMap(infos, "id");
        List<VideoBackendVo> videoBackendVos = videos.stream().map(v -> VideoBackendVo.init(v, infoMap.get(v.getUserId()))).collect(Collectors.toList());
        return new PageResult<>(page,pageSize,pageResult.getCounts(),videoBackendVos);
    }

    public MovementDetailVo getMovById(String id) {
        Movement movement = movementApi.getById(id);
        if (Objects.isNull(movement)){
            return new MovementDetailVo();
        }
        UserInfo userInfo = userInfoApi.findDetailById(movement.getUserId());
        return MovementDetailVo.init(userInfo,movement);
    }

    /**
     * 得到评论中
     *
     * @param page      页面
     * @param pageSize  页面大小
     * @param messageID 消息id
     * @return {@link PageResult}<{@link CommentsVo}>
     */
    public PageResult<CommentBackendVo> getCommentsByMid(Integer page, Integer pageSize, String messageID,String id,String sortOrder) {
        //分页获取所有该动态下的评论
        PageResult<Comment> pageResult = commentsApi.getAllComments(messageID,page,pageSize, CommentType.COMMENT);
        if (Objects.isNull(pageResult.getItems())||pageResult.getItems().size()==0){
            return new PageResult<>();
        }
        List<Comment> comments = pageResult.getItems();
        List<Long> userIds = comments.stream().map(Comment::getUserId).collect(Collectors.toList());
        List<UserInfo> userInfos = userInfoApi.findByIds(userIds);
        Map<Long, UserInfo> infoMap = CollUtil.fieldValueMap(userInfos, "id");

        ArrayList<CommentBackendVo> vos = new ArrayList<>();
        for (Comment comment : comments) {
            CommentBackendVo vo = CommentBackendVo.init(comment, infoMap.get(comment.getUserId()));
            vos.add(vo);
        }
        return new PageResult<>(page,pageSize,pageResult.getCounts(),vos);
    }

    public ResponseEntity userFreeze(Map<String, Object> map) {
        Integer userId = (Integer) map.get("userId");
        String freezingTime = (String) map.get("freezingTime");
/*        Integer freezingRange = (Integer) map.get("freezingRange");
        String reasonsForFreezing = (String) map.get("reasonsForFreezing");
        String frozenRemarks = (String) map.get("frozenRemarks");*/
        int days = 0;
        switch (freezingTime){
            case "1":
                days=3;
                break;
            case "2":
                days=7;
                break;
            case "3":
                days=-1;
                break;
            default:
                throw new BusinessException(ErrorResult.builder().errCode("冻结时间参数错误!").build());
        }
        //构建key
        String value = JSON.toJSONString(map);
        String key = RC.FREEZING_USER+userId;
        //存储多少天
        redisTemplate.opsForValue().set(key,value,days, TimeUnit.DAYS);
        //返回数据
        HashMap<String, String> hm = new HashMap<>();
        hm.put("message","冻结成功!");
        return ResponseEntity.ok(hm);
    }

    /**
     * 解冻用户
     *
     * @param map 地图
     * @return {@link ResponseEntity}
     */
    public ResponseEntity unfreeze(Map<String, Object> map) {
        Integer userId = (Integer) map.get("userId");
        //todo 解冻备注没有用到
        String key = RC.FREEZING_USER+userId;
        Boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey){
            redisTemplate.delete(key);
        }
        HashMap<String, String> hm = new HashMap<>();
        hm.put("message","解冻成功!");
        return ResponseEntity.ok(hm);
    }

    /**
     * 通过审计
     *
     * @param ids id
     * @return {@link Map}<{@link String}, {@link String}>
     */
    public Map<String, String> passOrNot(List<String> ids,Integer state) {
        //批量修改动态状态
       String message = movementApi.passOrNot(ids,state);
        HashMap<String, String> hm = new HashMap<>();
        hm.put("message",message);
        return hm;
    }

    public PageResult<Log> getUserLogById(Long userId, Integer page, Integer pageSize, String sortProp, String sortOrder) {
        Page<Log> logPage = new Page<>(page,pageSize);
        LambdaQueryWrapper<Log> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Log::getUserId,userId);
        wrapper.eq(StringUtils.isNotEmpty(sortProp),Log::getType,"0101");
        if (StringUtils.isNotEmpty(sortOrder)){
            if ("ascending".equals(sortOrder)){
                wrapper.orderByAsc(Log::getLogTime);
            }else {
                wrapper.orderByDesc(Log::getLogTime);
            }
        }
        logMapper.selectPage(logPage,wrapper);
        return new PageResult<>(page,pageSize,(int)logPage.getTotal(),logPage.getRecords());
    }
}
